#!/bin/bash

set -o errexit
set -o xtrace

test_dir=$(realpath "$(dirname "$0")")
. "${test_dir}/../functions"

function get_shard_parameter() {
    local cluster_name=$1
    local namespace=$2
    local parameter=${3:-lastCommittedOpTime}
    run_mongo 'db.isMaster().'${parameter}'' "clusterAdmin:clusterAdmin123456@${cluster_name}-rs0-0.${cluster_name}-rs0.${namespace}" "mongodb" "" "--quiet" \
        | egrep -v 'I NETWORK|W NETWORK|Error saving history file|Percona Server for MongoDB|connecting to:|Unable to reach primary for set|Implicit session:|versions do not match'
}

function main() {
    create_namespace $namespace
    deploy_operator

    kubectl_bin apply -f $conf_dir/secrets.yml -f $conf_dir/client.yml
    cluster="some-name"
    CLUSTER_SIZE=3

    desc 'create first PSMDB cluster'
    spinup_psmdb ${cluster}-rs0 $conf_dir/${cluster}-rs0.yml
    compare_kubectl "statefulset/${cluster}-rs0"
    simple_data_check "${cluster}-rs0" ${CLUSTER_SIZE}

    desc 'initiate migration from replicaset to sharded cluster'
    kubectl_bin patch psmdb/${cluster} --type json -p='[{"op":"add","path":"/spec/sharding","value":{"configsvrReplSet":{"size":'${CLUSTER_SIZE}',"volumeSpec":{"persistentVolumeClaim":{"resources":{"requests":{"storage":"3Gi"}}}}},"enabled":true,"mongos":{"size":1}}}]'
    sleep 10
    wait_for_running "${cluster}-rs0" "${CLUSTER_SIZE}" "false"
    wait_for_running "${cluster}-cfg" "${CLUSTER_SIZE}" "false"
    wait_cluster_consistency "${cluster}" "${CLUSTER_SIZE}"

    if [[ $(kubectl_bin get deployment/${cluster}-mongos -o jsonpath='{.status.readyReplicas}') -lt 1 ]]; then
        echo "Mongos hasn't been properly started. Exiting..."
        exit 1
    fi
    if [[ "$(kubectl_bin get sts/${cluster}-cfg -o jsonpath='{.status.replicas}')" \
          != "$(kubectl_bin get sts/${cluster}-cfg -o jsonpath='{.status.readyReplicas}')" ]]; then
        echo "Cfg pods haven't been properly started. Exiting..."
        exit 1
    fi
    # Migration to shards wipes out rs users. Let's recreate them
    run_mongos 'db.createUser({user: "myApp", pwd: "myPass", roles: [{ db: "myApp", role: "readWrite" }]})' \
                "userAdmin:userAdmin123456@${cluster}-mongos.${namespace}"

    simple_data_check "${cluster}" "${CLUSTER_SIZE}" 1 "-mongos"

    if [[ -z "$(get_shard_parameter ${cluster} ${namespace} lastCommitedOpTime)" ]] \
       && [[ -z "$(get_shard_parameter ${cluster} ${namespace} '$configServerState.opTime.ts')" ]]; then # for mongo 3.6
        echo "Sharded cluster does not work properly"
        exit 1
    fi

    desc 'Get back from sharded cluster to replicaset'
    kubectl_bin patch psmdb/${cluster} --type json -p='[{"op":"remove","path":"/spec/sharding"}]'
    sleep 10
    wait_for_running "${cluster}-rs0" "${CLUSTER_SIZE}" "true"

    simple_data_check "${cluster}-rs0" "${CLUSTER_SIZE}"

    if [[ ! -z "$(get_shard_parameter ${cluster} ${namespace} lastCommitedOpTime)" ]] \
       || [[ -n "$(kubectl_bin get deployments -o jsonpath='{.items[?(@.metadata.name == "'"${cluster}-mongos"'")].metadata.name}')" ]] \
       || [[ -n "$(kubectl_bin get service -o jsonpath='{.items[?(@.metadata.name == "'"${cluster}-mongos"'")].metadata.name}')" ]] \
       || [[ -n "$(kubectl_bin get service -o jsonpath='{.items[?(@.metadata.name == "'"${cluster}-cfg"'")].metadata.name}')" ]] \
       || [[ -n "$(kubectl_bin get statefulset -o jsonpath='{.items[?(@.metadata.name == "'"${cluster}-cfg"'")].metadata.name}')" ]]; then
        echo "Transition to replicaset cluster has not been done well. Cluster does not work properly or some leftovers still exist"
        exit 1
    fi

    desc 'cleanup'
    kubectl_bin delete -f "${src_dir}/deploy/crd.yaml" || :
    kubectl_bin delete -f "${src_dir}/deploy/rbac.yaml" || :
    kubectl_bin delete pvc --all
    destroy "${namespace}"
}

main
